/**
 * A convenient way to access a logical set of signals.
 * 
 * @author Jon Adams
 * 
 * @example SignalSets allow you to get predefined signals for many built in events
 * <listing version="3.0" >
package {
import org.osflash.signals.natives.sets.InteractiveObjectSignalSet;

import flash.display.Sprite;
import flash.events.Event;

public class Example extends Sprite {

private var button:Sprite;
private var buttonSignals:InteractiveObjectSignalSet;

public function Main() {
button = new Sprite();
button.graphics.beginFill(0xff0000);
button.graphics.drawRect(0, 0, 100, 100);
button.graphics.endFill();

buttonSignals = new InteractiveObjectSignalSet(button);
buttonSignals.click.add(handler);
buttonSignals.addedToStage.add(handler);
buttonSignals.enterFrame.addOnce(handler);

addChild(button);
}

private function handler(event:Event):void {
trace(event.target, "fired", event.type);
}
}
}
 * </listing>
 */
package org.osflash.signals.natives.sets;

import org.osflash.signals.natives.INativeDispatcher;
import org.osflash.signals.natives.NativeSignal;
import flash.events.Event;
import flash.events.IEventDispatcher;
import flash.utils.Dictionary;

class NativeSignalSet {
	public var numListeners(getNumListeners, never) : Int;
	public var signals(getSignals, never) : Array<Dynamic>;

	var target : IEventDispatcher;
	var _signals : Dictionary;
	public function new(target : IEventDispatcher) {
		_signals = new Dictionary();
		this.target = target;
	}

	/**
	 * Lazily instantiates a NativeSignal
	 * @throws ArgumentError <code>ArgumentError</code>: eventType must not be null.
	 */
	public function getNativeSignal(eventType : String, eventClass : Class<Dynamic> = null) : NativeSignal {
		if(null == eventType) throw new ArgumentError("eventType must not be null.");
		return _signals[eventType] ||= new NativeSignal(target, eventType, eventClass || Event);
	}

	/**
	 * The current number of listeners for the signal.
	 */
	public function getNumListeners() : Int {
		// TODO : This is horrid, it's very expensive to call this if there is a lot of signals.
		var count : Int = 0;
		for(var signal : INativeDispatcher in _signals) {
			count += signal.numListeners;
		}

		return count;
	}

	/**
	 * The signals in the SignalSet as an Array.
	 */
	public function getSignals() : Array<Dynamic> {
		// TODO : This is horrid, it's very expensive to call this if there is a lot of signals.
		var result : Array<Dynamic> = [];
		for(var signal : INativeDispatcher in _signals) {
			result[result.length] = signal;
		}

		return result;
	}

	/**
	 * Unsubscribes all listeners from all signals in the set.
	 */
	public function removeAll() : Void {
		for(var signal : INativeDispatcher in _signals) {
			signal.removeAll();
			delete;
			_signals[signal.eventType];
		}

	}

}

